package com.taotao.ds.at.util;

import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.statement.SQLDeleteStatement;
import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDeleteStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlUpdateStatement;
import com.alibaba.druid.sql.visitor.ParameterizedOutputVisitorUtils;
import com.alibaba.druid.util.JdbcConstants;
import com.taotao.druid.visitor.Delete2SelectVisitor;
import com.taotao.druid.visitor.Update2SelectVisitor;

import java.util.List;
import java.util.Objects;

/**
 * @author fanbeibei
 * @version 1.0
 * @date 2021/8/25 17:59
 */
public class DruidSqlParserUtil {
    private DruidSqlParserUtil() {

    }


    /**
     * 将update转化为select
     *
     * @param updateSql
     * @return
     */
    public static String updateToSelect(String updateSql, String dbType) {


        List<SQLStatement> asts = SQLUtils.parseStatements(updateSql, dbType);
        if (CollectionUtils.isEmpty(asts)) {
            throw new UnsupportedOperationException("Unsupported SQL: " + updateSql);
        }

        if (asts.size() > 1 && !(asts.stream().allMatch(statement -> statement instanceof SQLUpdateStatement))) {
            throw new UnsupportedOperationException("ONLY SUPPORT SAME TYPE UPDATE  MULTI SQL -" + updateSql);
        }


        StringBuilder selectSql = new StringBuilder();
        if (Objects.equals(dbType, JdbcConstants.MYSQL)) {

            MySqlUpdateStatement ast = (MySqlUpdateStatement) asts.get(0);

            System.out.println("--------------- update --------------" + ast.toLowerCaseString());

            Update2SelectVisitor updateToSelectVistor = new Update2SelectVisitor(selectSql);
            ast.accept(updateToSelectVistor);
        }


        return selectSql.toString();
    }


    /**
     * 将delete 转化为select
     *
     * @param deleteSql
     * @return
     */
    public static String deleteToSelect(String deleteSql, String dbType) {
        List<SQLStatement> asts = SQLUtils.parseStatements(deleteSql, dbType);
        if (CollectionUtils.isEmpty(asts)) {
            throw new UnsupportedOperationException("Unsupported SQL: " + deleteSql);
        }

        if (asts.size() > 1 && !asts.stream().allMatch(statement -> statement instanceof SQLDeleteStatement)) {
            throw new UnsupportedOperationException("ONLY SUPPORT SAME TYPE  DELETE MULTI SQL -" + deleteSql);
        }


        StringBuilder selectSql = new StringBuilder();
        if (Objects.equals(dbType, JdbcConstants.MYSQL)) {

            MySqlDeleteStatement ast = (MySqlDeleteStatement) asts.get(0);


            System.out.println("--------------- delete ---" + ast.toLowerCaseString());

            Delete2SelectVisitor visitor = new Delete2SelectVisitor(selectSql);

            ast.accept(visitor);

        }


        return selectSql.toString();
    }


    /**
     * 提取sql 模板，sql中参数转为?
     *
     * @param sql
     * @param dbType
     * @return
     */
    public String extractParameterizeSql(String sql, String dbType) {
        List<SQLStatement> asts = SQLUtils.parseStatements(sql, dbType);
        if (CollectionUtils.isEmpty(asts)) {
            throw new UnsupportedOperationException("Unsupported SQL: " + sql);
        }

        if (asts.size() > 1) {
            throw new UnsupportedOperationException("ONLY SUPPORT SINGLE SQL -" + sql);
        }

        return ParameterizedOutputVisitorUtils.parameterize(sql, dbType);
    }

}
